[No QA] Separate build and upload jobs in deploy workflow#81269
Open
roryabraham wants to merge 55 commits intomainfrom
Open
[No QA] Separate build and upload jobs in deploy workflow#81269roryabraham wants to merge 55 commits intomainfrom
roryabraham wants to merge 55 commits intomainfrom
Conversation
Split Android and iOS jobs into separate build and upload jobs to avoid rebuilding when uploads fail. Upload jobs are further split into critical store uploads and non-critical testing uploads that run in parallel. Co-authored-by: Cursor <cursoragent@cursor.com>
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Since GITHUB_ENV doesn't persist across jobs, we need to set the aabPath, ipaPath, and dsymPath environment variables after downloading the artifacts in the upload jobs. Co-authored-by: Cursor <cursoragent@cursor.com>
This comment has been minimized.
This comment has been minimized.
On production deploys, native builds are skipped so no artifacts are uploaded. Add conditional checks to skip download/upload steps that depend on build artifacts, while still allowing production rollout steps to run. Co-authored-by: Cursor <cursoragent@cursor.com>
This comment has been minimized.
This comment has been minimized.
Add SHOULD_DEPLOY_NATIVE output to prep job and reference it throughout the workflow instead of repeating the condition inline. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
The dSYM upload lane references Mobile-Expensify/iOS/Pods/FirebaseCrashlytics/upload-symbols, so the checkout needs to pull submodules. Co-authored-by: Cursor <cursoragent@cursor.com>
This comment has been minimized.
This comment has been minimized.
The dSYM upload lane uses the Crashlytics upload-symbols binary from Mobile-Expensify/iOS/Pods, so we need to install pods before running the upload. Co-authored-by: Cursor <cursoragent@cursor.com>
This comment has been minimized.
This comment has been minimized.
GitHub Actions expressions don't allow dot-notation access to keys containing hyphens. Changed needs.ios-upload-testflight.result to needs['ios-upload-testflight'].result and similarly for android-upload-google-play. Co-authored-by: Cursor <cursoragent@cursor.com>
This comment has been minimized.
This comment has been minimized.
Include android-build and ios-build in the postSlackMessageOnFailure job's needs array so build failures also trigger Slack notifications. Co-authored-by: Cursor <cursoragent@cursor.com>
This comment has been minimized.
This comment has been minimized.
Modified the upload_testflight_hybrid lane to read the IPA path from the ipaPath environment variable. This allows the lane to work when run in a separate job from the build, where the lane context is not available. Co-authored-by: Cursor <cursoragent@cursor.com>
This comment has been minimized.
This comment has been minimized.
Sourcemaps are always uploaded unconditionally now since no caller ever set this to false. Co-authored-by: Cursor <cursoragent@cursor.com>
This ensures the HybridApp verification builds exercise the exact same build pipeline as deploy and ad-hoc builds. Optimizations or fixes to the central buildAndroid/buildIOS workflows automatically apply here. Co-authored-by: Cursor <cursoragent@cursor.com>
This comment was marked as resolved.
This comment was marked as resolved.
Storybook is only built during deploys, not ad-hoc builds. Giving it its own job on a smaller runner keeps buildWeb.yml focused on the web app and removes an input that only one caller used. Co-authored-by: Cursor <cursoragent@cursor.com>
buildWeb.yml is now a pure build workflow — it builds the web app and uploads artifacts (sourcemaps, tar.gz, zip) but does not deploy. S3 deployment, Cloudflare cache purge, and deploy verification are now handled by dedicated jobs in the callers: - deploy.yml: new webDeploy job - buildAdHoc.yml: new deployWebAdHoc job Co-authored-by: Cursor <cursoragent@cursor.com>
Merge the variant-specific 1Password and ExportOptions.plist steps into single steps with conditionals, reducing duplication. Co-authored-by: Cursor <cursoragent@cursor.com>
buildStorybook uploads its output (dist/docs) as an artifact. webDeploy now depends on buildStorybook and downloads the docs into dist/docs before deploying to S3, preserving the original behavior. The download uses continue-on-error since buildStorybook itself is non-fatal. Co-authored-by: Cursor <cursoragent@cursor.com>
- Pin reusable build workflow refs to github.sha instead of github.ref to prevent artifact/version mismatches if the branch moves between prep and build execution. - Remove Node, MapBox, and CocoaPods setup from iosUploadTestflight since it only uploads a pre-built IPA via Fastlane. Co-authored-by: Cursor <cursoragent@cursor.com>
This comment was marked as resolved.
This comment was marked as resolved.
This was referenced Feb 21, 2026
When webBuild fails, webDeploy is skipped, so WEB_RESULT was reported as 'skipped' instead of 'failure'. Now checkDeploymentSuccess and postSlackMessageOnFailure depend on webBuild directly and propagate its failure into WEB_RESULT. Co-authored-by: Cursor <cursoragent@cursor.com>
This comment was marked as resolved.
This comment was marked as resolved.
- Pin webDeploy and buildStorybook checkouts to github.sha so deploy verification reads the same commit that was built, not a newer branch tip that may have landed in the interim. - Skip verifyHybridApp build jobs for Dependabot PRs since they lack the repository secrets required by 1Password/AWS setup steps. Co-authored-by: Cursor <cursoragent@cursor.com>
This comment was marked as resolved.
This comment was marked as resolved.
When buildWeb fails, deployWebAdHoc is skipped, so PR comments and build summaries reported Web as 'skipped' instead of 'failure'. Add buildWeb to the needs of postGithubComment and buildSummary, and propagate its failure into the WEB status. Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
Author
|
@codex review |
|
Codex Review: Didn't find any major issues. What shall we delve into next? ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
Contributor
Author
|
@Julesssss ready for review! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Explanation of Change
This PR refactors the CI/CD build infrastructure in two main ways:
1. Separate build and upload jobs in
deploy.ymlPreviously, if an upload failed (e.g., Google Play or TestFlight), we had to rebuild the entire app. Now Android and iOS each have dedicated build, upload, and submit jobs. Testing uploads (BrowserStack/Applause) run in parallel with store uploads and use
continue-on-error: trueso they can't block deployments. This also saves money by using large runners only for heavy builds, not while waiting on app store uploads.2. Unified callable build workflows
Extracted build logic into three reusable callable workflows that serve both
deploy.yml(Release) and test builds (Adhoc):buildAndroid.yml– Android HybridApp build via Rock Remote Build, with Gradle cache retry for durability. Produces AAB, APK (via bundletool), and sourcemap artifacts.buildIOS.yml– iOS HybridApp build via Rock Remote Build, with variant-specific provisioning profiles andExportOptions.plist. Includes CocoaPods caching. Produces IPA, dSYM, and sourcemap artifacts.buildWeb.yml– Web build with environment-specific build commands, optional S3 deployment, and Cloudflare cache purging.testBuild.ymlandtestBuildOnPush.ymlnow call these callable workflows directly (replacing the deletedbuildAdHoc.yml). Both support aFORCE_NATIVE_BUILDoption to bypass the Rock remote cache.Fixed Issues
$ #81257
Tests
N/A - GitHub Actions workflow changes will be validated on next deploy
Offline tests
N/A
QA Steps
N/A
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.